#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
#include <functional>
#include <variant>
#include <optional>
#include <sstream>
#include <type_traits>

class Cpp_Next {
public:
    using Value = std::variant<int, std::string>;
    using Result = std::variant<Value, std::string>;
    using Function = std::function<Result(const std::vector<std::string>&)>;

    Cpp_Next() {
        defineFunction("let", [this](const std::vector<std::string>& args) -> Result {
            if (args.size() >= 2) {
                std::string varName = args[0];
                std::string value = args[1];
                variables_[varName] = value;
                return varName;
            }
            return std::string("Error: Invalid arguments for let");
        });

        defineFunction("print", [this](const std::vector<std::string>& args) -> Result {
            for (const auto& arg : args) {
                if (variables_.count(arg)) {
                    std::cout << variables_[arg] << ' ';
                } else {
                    std::cout << arg << ' ';
                }
            }
            std::cout << '\n';
            return {};
        });

        defineFunction("add", [this](const std::vector<std::string>& args) -> Result {
            if (args.size() == 2) {
                int a = std::stoi(args[0]);
                int b = std::stoi(args[1]);
                return a + b;
            }
            return std::string("Error: Invalid arguments for add");
        });
    }

    void defineFunction(const std::string& name, Function func) {
        functions_[name] = func;
    }

    template<typename Func>
    void defineGenericFunction(const std::string& name, Func func) {
        functions_[name] = [func](const std::vector<std::string>& args) -> Result {
            return func(args);
        };
    }

    template<typename T>
    T getVariable(const std::string& name) {
        if (variables_.count(name)) {
            return std::get<T>(variables_[name]);
        }
        throw std::runtime_error("Variable not found");
    }

    void run(const std::string& code) {
        auto tokens = tokenize(code);
        executeCommand(tokens, 0);
    }

private:
    std::vector<std::string> tokenize(const std::string& code) {
        std::vector<std::string> tokens;
        std::string token;
        for (char ch : code) {
            if (isspace(ch)) {
                if (!token.empty()) {
                    tokens.push_back(token);
                    token.clear();
                }
            } else {
                token += ch;
            }
        }
        if (!token.empty()) tokens.push_back(token);
        return tokens;
    }

    void executeCommand(const std::vector<std::string>& tokens, size_t start) {
        if (tokens.empty() || start >= tokens.size()) return;

        std::string command = tokens[start];
        if (functions_.count(command)) {
            auto result = functions_[command](std::vector<std::string>(tokens.begin() + start + 1, tokens.end()));
            std::visit(overloaded {
                [](const Value& val) {
                    std::visit([](auto&& arg) { std::cout << arg << ' '; }, val);
                },
                [](const std::string& err) {
                    std::cerr << err << '\n';
                }
            }, result);
        }
    }

    template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
    template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;

    std::unordered_map<std::string, Function> functions_;
    std::unordered_map<std::string, std::variant<int, std::string>> variables_;
};

int main() {
    Cpp_Next script;

    // 定义一个泛型函数
    script.defineGenericFunction("concat", [](const std::vector<std::string>& args) -> Cpp_Next::Result {
        if (args.size() == 2) {
            return args[0] + args[1];
        }
        return std::string("Error: Invalid arguments for concat");
    });

    // 使用泛型函数
    script.run("let x Hello");
    script.run("let y World");
    script.run("print x y");
    script.run("concat x y");
    script.run("print x y");

    // 静态类型检查和断言
    static_assert(std::is_same_v<decltype(script.getVariable<std::string>("x")), std::string>, "Type mismatch");
    static_assert(std::is_same_v<decltype(script.getVariable<int>("y")), int>, "Type mismatch");

    // 错误处理示例
    script.run("add 10 20");  // 正常加法

    return 0;
}

